package com.nidu.demo.user.executor.command;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.cola.dto.SingleResponse;
import com.nidu.demo.company.ability.CompanyDomainService;
import com.nidu.demo.dept.ability.DepartmentDomainService;
import com.nidu.demo.dept.model.Department;
import com.nidu.demo.post.ability.PositionDomainService;
import com.nidu.demo.post.model.Position;
import com.nidu.demo.user.ability.UserDomainService;
import com.nidu.demo.user.convertor.UserConvertor;
import com.nidu.demo.user.dto.UserAddCmd;
import com.nidu.demo.user.dto.UserCO;
import com.nidu.demo.user.gateway.UserDepartmentGateway;
import com.nidu.demo.user.gateway.UserGateway;
import com.nidu.demo.user.gateway.UserPositionGateway;
import com.nidu.demo.user.gateway.UserRoleGateway;
import com.nidu.demo.user.model.User;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
public class UserAddCmdExe {

    private final UserConvertor convertor;

    private final UserDomainService domainService;

    private final CompanyDomainService companyDomainService;

    private final DepartmentDomainService departmentDomainService;

    private final PositionDomainService positionDomainService;

    private final UserGateway userGateway;

    private final UserDepartmentGateway userDeptGateway;

    private final UserPositionGateway userPostGateway;

    public SingleResponse<UserCO> execute(UserAddCmd cmd) {
        // 1. 转换为领域对象
        User user = User.create(cmd.getUsername(), cmd.getPassword(), cmd.getNickname(), cmd.getMobile(),
                cmd.getEmail(), cmd.getAvatar(), cmd.getGender(), cmd.getCompanyId(), cmd.getSortOrder());

        // 2. 加密密码
        user.setPassword(domainService.encodePassword(user.getPassword()));

        // 3. 校验对象
        // 3.1.检查公司是否启用
        companyDomainService.validateCompany(user.getCompanyId());
        // 3.2.检查对象是否存在
        domainService.validateDuplicate(user.getUsername(), user.getMobile(), user.getEmail(), user.getId());
        // 3.3.检查所有部门是否启用
        List<Department> depts = departmentDomainService.validateDepartmentList(cmd.getDeptIds());
        user.setDeptIds(depts.stream().map(Department::getId).collect(Collectors.toSet()));
        // 3.4.检查所有岗位是否启用
        List<Position> posts = this.positionDomainService.validatePositionList(cmd.getPostIds());
        user.setPostIds(posts.stream().map(Position::getId).collect(Collectors.toSet()));

        // 4. 保存用户、部门和职位信息
        User save = this.addUserInfo(user);

        // 5. 转换为DTO返回
        UserCO userCO = convertor.toClientObject(save);

        return SingleResponse.of(userCO);
    }

    @Transactional
    private User addUserInfo(User user) {
        User save = userGateway.create(user);
        if (!CollUtil.isEmpty(user.getDeptIds())) {
            userDeptGateway.bindUserDepts(user.getId(), user.getDeptIds());
        }
        if (!CollUtil.isEmpty(user.getPostIds())) {
            userPostGateway.bindUserPosts(user.getId(), user.getPostIds());
        }
        return save;
    }
}
